#include "at24cxx.h"
#include "i2c.h"
#define AT24CXX_DEV_ADDRESS     0xA0  //写指令IIC地址
#define AT24CXX_DELAY_MS        HAL_Delay

#define AT24CXX_MAX_TIMEOUT 200 //i2c最大阻塞时间
#define AT24CXX_MAX_TRIALS 	200  //i2c判断次数
#define I2Cx 				hi2c1

//值得注意的是AT24C128的地址是16位的，并且内部写EPPROM空间的时间最长为5ms

/*
 Memory Organization
 AT24C32/64, 32K/64K SERIAL EEPROM: The 32K/64K is
 internally organized as 256 pages of 32 bytes each. Ran-
 dom word addressing requires a 12/13 bit data word
 address.

 32 bytes each===每个页共32个字节
 */

static uint8_t AT24CXX_WriteByte(uint16_t reg_address, uint8_t data)
{
	if (HAL_OK
			== HAL_I2C_Mem_Write(&I2Cx, AT24CXX_DEV_ADDRESS, reg_address, I2C_MEMADD_SIZE_16BIT, &data, 1,
					AT24CXX_MAX_TIMEOUT)) {
		while (HAL_I2C_GetState(&I2Cx) != HAL_I2C_STATE_READY) {
		}
		/* Check if the EEPROM is ready for a new operation */
		while (HAL_I2C_IsDeviceReady(&I2Cx, AT24CXX_DEV_ADDRESS, AT24CXX_MAX_TRIALS, AT24CXX_MAX_TIMEOUT) == HAL_TIMEOUT) {
		}
		/* Wait for the end of the transfer */
		while (HAL_I2C_GetState(&I2Cx) != HAL_I2C_STATE_READY) {
		}
		return HAL_OK;
	} else {
		return HAL_ERROR;
	}
}

static uint8_t AT24CXX_ReadByte(uint16_t reg_address)
{
	uint8_t data = 0;
	HAL_I2C_Mem_Read(&I2Cx, AT24CXX_DEV_ADDRESS, reg_address, I2C_MEMADD_SIZE_16BIT, &data, 2, AT24CXX_MAX_TIMEOUT);
	return data;
}

/****************************************************************************
 * 名    称: void AT24C02_Write(uint8_t WriteAddr,uint8_t *pBuffer,uint8_t WriteNum)
 * 功    能：从AT24C02里面的指定地址开始写入指定个数的数据
 * 入口参数：WriteAddr :开始写入的地址  0~255
 pBuffer  :数据数组首地址
 WriteNum:要写入数据的个数
 * 返回参数：
 * 说    明：  
 ****************************************************************************/
void AT24C64_Write(uint16_t WriteAddr, uint8_t *pBuffer, uint8_t WriteNum)
{
	while (WriteNum--) {
		AT24CXX_WriteByte(WriteAddr, *pBuffer);
		WriteAddr++;
		pBuffer++;
	}
	AT24CXX_DELAY_MS(5);
}

/****************************************************************************
 * 名    称: void AT24C02_Read(uint8_t ReadAddr,uint8_t *pBuffer,uint8_t ReadNum)
 * 功    能：从AT24C02里面的指定地址开始读出指定个数的数据
 * 入口参数：ReadAddr :开始读出的地址  0~255
 pBuffer  :数据数组首地址
 ReadNum:要读出数据的个数
 * 返回参数：
 * 说    明：  
 ****************************************************************************/
void AT24C64_Read(uint16_t ReadAddr, uint8_t *pBuffer, uint8_t ReadNum)
{
	while (ReadNum--) {
		*pBuffer++ = AT24CXX_ReadByte(ReadAddr++);
	}
}
